home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 7
/
Apprentice-Release7.iso
/
Environments
/
PowerFantasm™ 4.19a
/
PowerFantasm™
/
F4_EXAMPLES
/
Other people examples
/
Stars
/
stars.s
< prev
Wrap
Text File
|
1996-12-04
|
7KB
|
282 lines
stars_demo:
*********************************************************************************
** Stars
** by Allan Jensen (maccoder@geocities.com)
** Further info: Read the doc
********************************************************************************
**Set up equates
n_stars: equ 1200 *can easily handle more (too many requires some alterations)
dim_one: equ 6*n_stars *3d coords for stars (halfword)
black: equ 0 *definition black
screenx: equ 512
screeny: equ 400
speed: equ 2 *starspeed
zoom: equ 128 *how close the stars
z_const: equ 600
*bss section
bss: reg r30
res_clut: rs.w 1
handle_one: rs.w 1
pointer_one: rs.w 1
screen_buffer: rs.w 1 *Where our offscreen screen buffer starts
rect_top: rs.h 1
rect_left: rs.h 1
rect_bottom: rs.h 1
rect_right: rs.h 1
*********************************************************************************
ENTRY
start_up
bl init_mac
bl init_graph_lib
Xcall HideCursor
li r3,dim_one
Xcall NewHandle
stw r3,handle_one(`bss)
mr r20,r3
Xcall HLock
mr r3,r20
lwz r3,(r3)
stw r3,pointer_one(`bss)
li r3,screenx*2 *width
li r4,screeny+2*64 *height
mullw r3,r3,r4 *size we need
addi r3,r3,10*(2*screenx) *plus a bit just in case
Xcall NewHandle
mr r20,r3 *save handle
Xcall HLock *We want a locked handle so we can use the pointer
lwz r20,(r20) *the pointer to the data
check_octal:
mr r3,r20
andi. r3,r3,%111 *and with 7
beq is_aligned
addi r20,r20,1
b check_octal
is_aligned:
stw r20,screen_buffer(`bss)
li r3,130
bl load_clut
stw r3,res_clut(`bss)
lwz r3,res_clut(`bss)
lwz r3,(r3)
bl do_clut *remember to use a white to black fading palette
li r3,black
bl cls_256
bl calc_rect *screen setup stuff (by Lightsoft, wahey!)
bl make_table *randomize coordinates
fire_loop:
bl clear_offscreen *clear by ....Lightsoft...again
bl do_stars *convert to 2d, move the star and plot it
bl splat_screen *another routine by guess who
bl getkey_turbo
cmpwi r3,0
beq fire_loop
QUIT:
li r3,black
bl cls_256
lwz r3,handle_one(`bss)
Xcall HUnlock
Xcall ShowCursor
tidy_up
blr
****************** Routines ********************
**Calculate viewable rectangle from screen size by Lightsoft
calc_rect:
mflr r29
lwz r3,vis_height(rtoc) *visible screen height
srwi r3,r3,1 *middle of screen
subi r3,r3,screeny/2 *top of viewrect
sth r3,rect_top(`bss)
lwz r3,vis_width(rtoc)
srwi r3,r3,1
subi r3,r3,(screenx/2)-8
**make sure its a multiple of 8
mr r4,r3
make_x_8:
mr r3,r4
andi r3,r3,%111
beq is_8
subi r4,r4,1
b make_x_8
is_8:
sth r4,rect_left(`bss)
mtlr r29
blr
*This routine calculates a table full of coordinates (x,y,z)
*x is a random number between 0 and screen width (screenx)
*y is a random number between 0 and screen height (screeny)
*z is a random number and so on and so on and so on and......
*Remember that coords must lie within screen (well, obviously)
make_table:
mflr r29
lwz r14,pointer_one(`bss)
li r9,n_stars
table_loop:
Xcall Random
andi r3,r3,$fff
cmpwi r3,screenx-1
bgt table_loop
sth r3,(r14)
addi r14,r14,2
y_calc::
Xcall Random
andi r3,r3,$fff
cmpwi r3,screeny-1
bgt y_calc
sth r3,(r14)
addi r14,r14,2
z_calc:
Xcall Random *experiment with the z-values to decide what you like best
andi r3,r3,$fff
cmpwi r3,z_const
bgt z_calc
sth r3,(r14)
addi r14,r14,2
subi r9,r9,1
cmpwi r9,0
bgt table_loop
mtlr r29
blr
*Converts the 3d coords to 2d, moves the star and plots it
*Uses formula 3d->2d:
*x1 = (x*zoomconst)/z
*y1 = (y*zoomconst)/z
*Extra bits explained in doc (it's a long story)
do_stars:
mflr r29
lwz r10,pointer_one(`bss)
lwz r6,screen_buffer(`bss)
li r9,n_stars
2d_loop:
lhz r3,(r10) *first we get the coords
addi r10,r10,2
lhz r4,(r10)
addi r10,r10,2
lhz r5,(r10)
subi r3,r3,screenx/2 *the we convert them to 2d
slwi r3,r3,7 *instead of muls with zoom
divw r3,r3,r5
addi r3,r3,screenx/2
subi r4,r4,screeny/2
slwi r4,r4,7
divw r4,r4,r5
addi r4,r4,screeny/2
cmpwi r5,speed+1 *let's check if the star expires
bgt closer
li r7,z_const *put it far away
sth r7,(r10)
subi r10,r10,4
b 2d_loop
closer:
subi r5,r5,speed *let's move the star closer
sth r5,(r10)
addi r10,r10,2
cmpwi r3,screenx-1 *some bounds checking
bgt next_star
cmpwi r3,0
blt next_star
cmpwi r4,screeny-1
bgt next_star
cmpwi r4,0
blt next_star
li r12,3 *futile attempt to make colours look nice :)
divw r5,r5,r12
*plot the star
slwi r4,r4,10 *instead of mulli with screenx
add r4,r4,r6
add r4,r4,r3
stb r5,(r4)
next_star:
subi r9,r9,1
cmpwi r9,0
bgt 2d_loop
mtlr r29
blr
*Lightsoft...again
clear_offscreen:
li r3,screenx*2
li r4,screenx-1 *height
mullw r3,r3,r4
srwi r3,r3,2 *div by 4 for longs
mtctr r3
lwz r3,screen_buffer(`bss)
li r4,0
clear_loop:
stw r4,(r3)
addi r3,r3,4
bdnz clear_loop
blr
*and again....
splat_screen:
**Each line is 125 longs, and there are 400 lines. The addresses we get from y_tab
lwz r3,y_tab(rtoc) *address of the start of each scan line
lhz r4,rect_top(`bss)
slwi r4,r4,2
add r3,r3,r4 *Offset splat in y direction*4
li r8,screeny *400 lines per screen
lwz r6,screen_buffer(`bss) *source data
subi r6,r6,8 *for pre-inc addressing mode
li r14,2*screenx
li r7,64
mullw r7,r7,r14
add r6,r6,r7
lhz r22,rect_left(`bss) *get x offset
li r4,(screenx/4)/2 *124 longs/line
addi r6,r6,32 *move right 32
**Offset offsceen by 32
subi r3,r3,4
splat_loop:
mtctr r4
lwzu r5,4(r3) *start addr of this scan line
add r5,r5,r22 *offset splat in x direction
line_loop:
lfdu f0,8(r6)
stfdu f0,8(r5)
bdnz line_loop *complete the line to 546
subic. r8,r8,1
addi r6,r6,(2*screenx-screenx+32)+32 *point to next line
bne splat_loop *do next line
blr
load_clut:
mflr r28
mr r4,r3
li r3,"cl"
li r5,16
slw r3,r3,r5
li r5,"ut"
or r3,r3,r5
Xcall GetResource
mtlr r28
blr
do_clut:
mflr r29
mr r5,r3
li r3,0
li r4,255
Xcall SetEntries
mtlr r29
blr
*******************************************************************************************
global stars_demo
extern init_graph_lib,init_mac,cls_256,getkey_turbo
extern_data y_tab,screen_base
extern_data vis_width,vis_height